
#ifndef _TTG_SERVICES_DEVICEINFO_
#define _TTG_SERVICES_DEVICEINFO_

#include "Common/Structures.h"
#include "Common/Extras.h"

namespace ttg
{
	namespace services
	{
		//Contains information about one subdevice and its usage (e.g. "Core #2").
		class SubDeviceInfo :public ttg::structures::NamedObject,
							 public ttg::structures::SerializableObject
		{
			private:
				float usage;			//normalized current usage (from 0.0 upto 1.0).
				float max_value;		//non-normalized maximum achievable value.
				std::string unit_name;	//name of measuring unit (e.g "%" or "MB").
			public:
				//Default constructor for deserializer.
				inline SubDeviceInfo()
					:NamedObject("")
				{ usage = 0.0f; max_value = 1.0f; }
				//Creates information about subdevice and its measuring metric.
				inline SubDeviceInfo(const char *name, const char *unit_name, float max_value)
					:NamedObject(name)
				{ this->unit_name = unit_name; usage = 0.0f; this->max_value = max_value; }
				//SerializableObject member.
				virtual void serialize(extras::serialization::Serializer &serializer);
				//SerializableObject member.
				virtual void deserialize(extras::serialization::DeSerializer &deserializer);
				//Returns string suffix for measuring unit (e.g. "%").
				inline const char *getMeasuringUnit() const
				{ return unit_name.c_str(); }
				//Returns current usage (normalized from 0.0 to 1.0).
				inline float getUsage() const
				{ return usage; }
				//Returns non-normalized maximum achievable value.
				inline float getMaxValue()
				{ return max_value; }
				//Sets current usage.
				inline void setUsage(float usage)
				{ this->usage = usage; }
		};

		//Contains information about one device and its usage.
		class DeviceInfo :public ttg::structures::NamedObject,
						  public ttg::structures::SerializableObject
		{
			private:
				std::string description;					//Description of the device (e.g. CPU model).
				std::vector<SubDeviceInfo *> subdevices;	//All subdevices.
				float usage;
				float max_value;
				std::string unit_name;
			public:
				//Default constructor for deserializer.
				inline DeviceInfo()
					:NamedObject("")
				{ usage = 0.0f; max_value = 1.0f;}
				//Creates empty information about device.
				inline DeviceInfo(const char *name, const char *description, const char *unit_name, float max_value)
					:NamedObject(name)
				{ this->description = description; this->unit_name = unit_name;
				  usage = 0.0f; this->max_value = max_value; }
				//SerializableObject member.
				virtual void serialize(extras::serialization::Serializer &serializer);
				//SerializableObject member.
				virtual void deserialize(extras::serialization::DeSerializer &deserializer);
				//Returns description of the device (for user).
				inline const char *getDescription() const
				{ return description.c_str(); }
				//Returns string suffix for measuring unit (e.g. "%").
				inline const char *getMeasuringUnit() const
				{ return unit_name.c_str(); }
				//Returns current usage (normalized).
				inline float getUsage() const
				{ return usage; }
				//Sets current usage (normalized).
				inline void setUsage(float usage)
				{ this->usage = usage; }
				//Returns non-normalized maximum achievable value.
				inline float getMaxValue()
				{ return max_value; }
				//Returns information about all subdevices of the current device.
				inline std::vector<SubDeviceInfo *> &getSubDevices()
				{ return subdevices; }
				//Adds new subdevice information.
				//Note: it will be released by destructor.
				inline void addSubDevice(SubDeviceInfo *info)
				{ subdevices.push_back(info); }
				~DeviceInfo()
				{ SAFE_DELETE_CONTENT(&subdevices); }
		};
	}
}

#endif
